package com.tsd.common.controller;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.tsd.core.constants.Constants;
import com.tsd.common.vo.WxPayNotifyResultVo;
import com.tsd.core.datasource.DataSourceContextHolder;
import com.tsd.core.utils.ExceptionUtil;
import com.tsd.core.utils.HlpUtils;
import com.tsd.core.utils.HttpUtil;
import com.tsd.wxpay.WxPayConfig4SysSettingService;
import com.tsd.wxpay.entity.WeixinPayNotifyLogExt;
import com.tsd.wxpay.service.WeixinPayNotifyLogService;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;

/**
 * 描述：资产关联微信支付的 控制层
 *
 * @author huawei
 * @date 2022/04/16 12:16:55
 */
public class BaseWxPayNotifyController extends BaseController {

    private static final Logger LOGGER = LoggerFactory.getLogger(BaseWxPayNotifyController.class);

    @Autowired
    private WxPayService wxPayService;
    @Resource
    private WxPayConfig4SysSettingService wxPayConfig4SysSettingService;
    @Resource
    private WeixinPayNotifyLogService weixinPayNotifyLogService;

    /**
     * 微信支付通知处理
     * 如下这段xml是收到的通知信息样本
     * <xml><appid><![CDATA[wx8b466afd8afe3f26]]></appid>
     * <attach><![CDATA[{"account_set_sid":"tsd_mall"}]]></attach>
     * <bank_type><![CDATA[OTHERS]]></bank_type>
     * <cash_fee><![CDATA[1100]]></cash_fee>
     * <fee_type><![CDATA[CNY]]></fee_type>
     * <is_subscribe><![CDATA[N]]></is_subscribe>
     * <mch_id><![CDATA[1390359002]]></mch_id>
     * <nonce_str><![CDATA[1657322524675]]></nonce_str>
     * <openid><![CDATA[oPzUY0VBme-5RAqJLyaJMklKOuWg]]></openid>
     * <out_trade_no><![CDATA[1c24238601c8466a98e0aeebe7bdb787]]></out_trade_no>
     * <result_code><![CDATA[SUCCESS]]></result_code>
     * <return_code><![CDATA[SUCCESS]]></return_code>
     * <sign><![CDATA[E5DEC55056C22E5D42E41BCD38022FC6]]></sign>
     * <time_end><![CDATA[20220709072300]]></time_end>
     * <total_fee>1100</total_fee>
     * <trade_type><![CDATA[JSAPI]]></trade_type>
     * <transaction_id><![CDATA[4200001513202207092013043988]]></transaction_id>
     * </xml>
     *
     * @param request 请求内容
     * @return 操作结果
     */
    protected WxPayNotifyResultVo procNotify(HttpServletRequest request, String bizType) {
        LOGGER.info("【微信支付通知开始】");
        WxPayOrderNotifyResult result;
        String xmlResult;
        Long notifyId;
        try {
            xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
        } catch (IOException e) {
            LOGGER.error("【微信支付通知】：{}", "获取回调消息内容错误!");
            LOGGER.error(ExceptionUtil.getStackTraceFromException(e));
            return WxPayNotifyResultVo.fail(e.getMessage());
        }
        try {
            // 2022-01-26 wudw 为了支持多账套的方式，需要从result里面的attach中获取账套id，
            // 所以将原来调用wxPayService.parseOrderNotifyResult(xmlResult);对应的实现复制到这里，并进行相应改动
            try {
                LOGGER.info("【微信支付通知】参数：{}", xmlResult);
                result = WxPayOrderNotifyResult.fromXML(xmlResult);
                LOGGER.info("【微信支付通知】解析后的对象：{}", result);
                String attach_str = result.getAttach();
                if (!HlpUtils.isEmpty(attach_str) && JSONUtil.isJsonObj(attach_str)) {
                    Map<String, Object> attach = JSON.parseObject(result.getAttach());
                    String account_set_sid = HttpUtil.getAccountSet(request);
                    DataSourceContextHolder.setDataSourceType(account_set_sid);
                }
                wxPayService.setConfig(wxPayConfig4SysSettingService.getWxPayConfig(null));
                result.checkResult(wxPayService, wxPayService.getConfig().getSignType(), false);

                // 保存日志
                WeixinPayNotifyLogExt logExt = new WeixinPayNotifyLogExt(result);
                logExt.setBiz_type(bizType);
                weixinPayNotifyLogService.saveWeixinPayNotifyLog(logExt, null);
                notifyId = logExt.getId();
            } catch (WxPayException e) {
                LOGGER.error(e.getMessage(), e);
                throw e;
            } catch (Exception e) {
                LOGGER.error(e.getMessage(), e);
                throw new WxPayException("【微信支付通知】发生异常，" + e.getMessage(), e);
            }
        } catch (WxPayException e) {
            LOGGER.error("【微信支付通知】回调失败：{}", ExceptionUtil.getStackTraceFromException(e));
            return WxPayNotifyResultVo.fail(e.getMessage());
        }
        LOGGER.info("【微信支付通知处理结束】响应结果：{}", "处理成功!");
        return WxPayNotifyResultVo.success("处理成功!", notifyId);
    }

}
